package com.noahsloan.nutils.streams;
 
import java.io.IOException;
import java.io.OutputStream;

/**
 * Intended to be used a debugging tool, EchoOutputStream takes data from a
 * write, and writes it to multiple output streams.
 * 
 * @author noah
 * 
 */
public class EchoOutputStream extends OutputStream {

    private final OutputStream[] echos;

    private final boolean ignoreErrors;

    /**
     * For 1 stream, automatically echos to System.out (otherwise, why would you
     * wrap just 1 stream?)
     * 
     * @param out
     */
    public EchoOutputStream(OutputStream out) {
        this(false, out, System.out);
    }

    public EchoOutputStream(OutputStream... echos) {
        this(false, echos);
    }

    /**
     * If ignoreErrors is on, the EchoOutputStream will continue writing to all
     * streams without errors (if any) until it is closed.
     * 
     * @param ignoreErrors
     *            should streams that have errors simply be closed and removed
     *            or should an exception be thrown?
     * @param echos
     *            the streams to write to.
     */
    public EchoOutputStream(boolean ignoreErrors, OutputStream... echos) {
        this.echos = echos;
        this.ignoreErrors = ignoreErrors;
    }

    @Override
    /**
     * @see OutputStream#write(int)
     */
    public void write(int b) throws IOException {
        for (int i = 0; i < echos.length; i++) {
            try {
                if (echos[i] != null) {
                    echos[i].write(b);
                }
            } catch (IOException e) {
                if (ignoreErrors) {
                    echos[i].close();
                    echos[i] = null;
                } else {
                    throw e;
                }
            }
        }
    }

    @Override
    /**
     * @see OutputStream#write(byte[])
     */
    public void write(byte[] buffer) throws IOException {
        this.write(buffer, 0, buffer.length);
    }

    @Override
    /**
     * @see OutputStream#write(byte[],int,int)
     */
    public void write(byte[] buffer, int start, int len) throws IOException {
        for (int i = 0; i < echos.length; i++) {
            try {
                if (echos[i] != null) {
                    echos[i].write(buffer, start, len);
                }
            } catch (IOException e) {
                if (ignoreErrors) {
                    echos[i].close();
                    echos[i] = null;
                } else {
                    throw e;
                }
            }
        }
    }

    @Override
    /**
     * Closes ALL the OutputStreams (remember this will close System.out if you
     * used the 1 parameter constructor)
     */
    public void close() throws IOException {
        for (OutputStream echo : echos) {
            if (echo != null) {
                echo.close();
            }
        }
    }
}
